장고 모델만들기 | ✅저자: 이유정(박사)
LIFE CYCLE IN DJANGO
CLIENT (브라우저)
사용자가 웹사이트 주소를 입력하거나 버튼을 클릭하여 요청을 보냅니다.
WEB SERVER (Nginx or Apache)
- 클라이언트로부터 받은 요청을 처리할 준비가 된 Python 서버 애플리케이션(Wsgi 서버)에게 전달합니다.
- 정적 파일(이미지, CSS, JS 등)은 여기서 직접 제공하기도 합니다.
WSGI (Gunicorn or uWSGI)
: (WSGI) Web Server Gateway Interface
- WSGI는 Python 애플리케이션과 웹 서버 간의 인터페이스입니다.
- Django는 WSGI를 통해 요청을 받아서 내부적으로 처리합니다.
- Django 프로젝트의 진입점: wsgi.py
REQUEST → Middleware
- Django는 요청을 받자마자 먼저 미들웨어(Middleware)를 거칩니다.
- 미들웨어는 요청(Request)을 가로채어 공통 처리를 수행합니다.
- 예: 사용자 인증 검사, 세션 처리, CORS(교차 출처 리소스 공유) 허용 여부 등
URL ROUTER (urls.py)
- 미들웨어를 통과한 요청은 URLConf로 전달되어 URL에 맞는 View 함수 또는 클래스를 결정합니다.
- 예: articles/3/
→ views.article_detail(request, id=3)
VIEWS (views.py)
- 뷰는 실제로 비즈니스 로직을 처리하는 곳입니다.
- 요청을 분석하고, 필요한 데이터를 가져오고, 응답을 준비합니다.
- ORM 또는 외부 API와 상호작용이 여기서 발생합니다.
ORM ↔ DATABASE (이미지에서 빨간색 박스)
- 뷰에서 데이터가 필요하면, ORM(Object Relational Mapping)을 사용해 데이터베이스와 상호작용합니다.
- 예: Article.objects.get(id=3)
- Django의 ORM은 SQL 없이도 Python 코드로 DB 조작이 가능하게 해줌
- 지원되는 DB: PostgreSQL, MySQL, SQLite 등등..
CONTEXT PROCESSORS
- 뷰에서 템플릿에 전달할 변수들을 딕셔너리 형태로 반환합니다.
- 예: return render(request, 'article.html', {'title': 'Django'})
- settings.py
에 등록된 context processor는 모든 템플릿에서 공통 사용 가능
TEMPLATE SYSTEM
- Django의 템플릿 언어를 이용해 HTML을 동적으로 생성합니다.
- {{ title }}
, {% for article in articles %}
같은 문법 사용
TEMPLATE TAGS
- 반복문, 조건문, 필터 등 템플릿에서 사용하는 태그 기능을 제공합니다.
- 예: {% if user.is_authenticated %}
, {% for post in posts %}
RESPONSE → Middleware
- 생성된 응답(HTML, JSON 등)은 다시 미들웨어를 거칩니다.
- 예: 응답 로그 남기기, 응답 압축, 쿠키 설정 등
WSGI → WEB SERVER → CLIENT
- 최종적으로 응답이 WSGI를 거쳐 웹 서버로 전달되고, 브라우저에 표시됩니다.
🔹 SQL과 NoSQL 데이터베이스의 차이점 데이터 저장 방식 (Data Storage)
◽ SQL (관계형 데이터베이스)
- 1970년대에 개발됨.
- 데이터를 표(테이블) 형태로 저장함.
- SQL이라는 언어를 사용해서 데이터를 관리함.
- 당시에는 저장공간이 매우 비쌌기 때문에,
- 같은 데이터를 반복하지 않고,
- 데이터를 효율적으로 나누어 저장하는 것이 중요했음.
- 특징:
- 구조가 복잡하고 딱 정해져 있어야 함 (정형화된 스키마).
- 서버의 성능을 늘리는 데 비용이 많이 듦 (수직 확장).
🧠 쉽게 말하면: "공간을 아끼기 위해 데이터를 잘게 나눠 정리해서 저장하는 방식입니다.
◽ NoSQL (비관계형 데이터베이스)
- 2000년대 후반에 등장.
- 이름은 NoSQL이지만 뜻은 "SQL만 사용하지 않는" 이라는 의미도 포함됨.
- 특징:
- 데이터를 자유로운 형태(예: JSON)로 저장 가능.
- 속도 빠름, 규모 확장 쉬움, 변화에 유연함.
- 앱을 자주 바꾸는 경우, 개발자에게 더 쉬움.
🧠 쉽게 말하면: "데이터를 자유롭게 넣을 수 있고, 빨리 처리하고, 앱이 자주 바뀌어도 편하게 쓸 수 있는 방식이에요."
🔹 모델이란?
- 모델은 데이터를 정의하고 저장하는 핵심 구성요소입니다.
- 데이터의 필드(컬럼)와 동작(속성)을 정의합니다.
- 일반적으로 모델 하나는 데이터베이스 테이블 하나에 대응됩니다.
🔹 Django에서 모델의 특징
- 모델은 파이썬 클래스로 정의됩니다.
django.db.models.Model
을 상속합니다.- 모델의 속성(변수)은 데이터베이스 필드에 해당됩니다.
- Django는 모델을 기반으로 자동으로 CRUD(Create, Read, Update, Delete) 기능을 제공합니다.
# polls/models.py
from django.db import models
class Question(models.Model): # 릴레이션
#속성question_text
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField("date published")
class Choice(models.Model):
question=models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
🔁 관계형 데이터베이스 vs Django 모델 구조 매칭
관계형 개념 | 예시 값(아래표 기준) | 모델 대응 |
---|---|---|
릴레이션 | Question 테이블 | class Question |
속성(Attribute) | question_text, pub_date | 필드 정의 |
튜플(Tuple) | 질문 한 줄 데이터 | Question 객체 하나 |
기본 키(PK) | id(PK) (1, 2) | 자동 생성되는 id |
릴레이션 인스턴스 | Question 테이블에 등록된 <br>모든 데이터 | Question.objects.all() |
🔹 테이블 구조로 변환한 모습
Question 테이블 (질문 테이블)
id (PK) | question_text | pub_date |
---|---|---|
1 | 당신의 취미는 무엇인가요? | 2025-05-10 10:00:00 |
2 | 좋아하는 색은 무엇인가요? | 2025-05-11 09:30:00 |
id
: Django가 자동으로 생성하는 기본 키 (Primary Key)question_text
: 질문 내용pub_date
: 개시 날짜와 시간 (published date)
Choice 테이블 (선택지 테이블)
id (PK) | question_id (FK) | choice_text | votes |
---|---|---|---|
1 | 1 | 독서 | 5 |
2 | 1 | 운동 | 3 |
3 | 1 | 영화 | 2 |
4 | 2 | 파랑 | 7 |
5 | 2 | 빨강 | 4 |
question_id
:Question
테이블의id
를 참조하는 외래키 (ForeignKey)
→ 이 선택지가 어느 질문에 속하는지 나타냄choice_text
: 선택지 내용votes
: 해당 선택지가 받은 투표 수
◽ 위의 테이블을 UI에 연동시킨다면:
질문 목록 페이지 (/questions/
)
📋 설문조사 목록
1. 당신의 취미는 무엇인가요? [투표하기]
2. 좋아하는 색은 무엇인가요? [투표하기]
첫 번째 질문 상세 페이지 (/questions/1/
)
🗳️ 설문조사: 당신의 취미는 무엇인가요?
- [ ] 독서
- [ ] 운동
- [ ] 영화
[투표 제출]
두 번째 질문 상세 페이지 (/questions/2/
)
🗳️ 설문조사: 좋아하는 색은 무엇인가요?
- [ ] 파랑
- [ ] 빨강
[투표 제출]
투표 결과 페이지 (/questions/2/results/
)
🗳️ 설문조사: 좋아하는 색은 무엇인가요?
- [ ] 파랑
- [ ] 빨강
[투표 제출]
🔸 관계형 데이터 구조로 보면?
관계:
- 1개의 질문(Question) → 여러 개의 선택지(Choice)
- Question(1) : Choice(N) → 1:N (일대다 관계) 구조입니다.
외래키(ForeignKey)는 항상 N 쪽 (여러 개가 있는 쪽)에 위치합니다:
- 왜냐하면, 선택지(Choice)는 반드시 자신이 어떤 질문에 속하는지 알아야 하기 때문입니다.
- 반대로 질문(Question)은 자신의 선택지를 몰라도 됩니다. 선택지들이 자기를 "참조"하면 되니까요.
선택지(Choice) | 관련 질문(Question) |
---|---|
"독서" | "당신의 취미는 무엇인가요?" |
"운동" | "당신의 취미는 무엇인가요?" |
"파랑" | "좋아하는 색은 무엇인가요?" |
"독서"는 어떤 질문에 속하는지 알아야 하므로, question_id = 1 같은 식으로 연결됩니다. |
Django 모델 구조에서 이 관계를 표현하면?
class Choice(models.Model):
question=models.ForeignKey(Question, on_delete=models.CASCADE)
ForeignKey
는 Choice 모델에 들어갑니다.- 이 외래키는 Question 테이블의 id (PK) 와 연결됩니다.
- 즉,
Choice.question_id
는Question.id
를 참조합니다.
[다른 예시]
Category 테이블
id (PK) | name |
---|---|
1 | 전자제품 |
2 | 의류 |
3 | 식품 |
id
: Primary Key (자동으로 생성됨)name
: 카테고리 이름
Product 테이블
id (PK) | category_id (FK) | name | price |
---|---|---|---|
1 | 1 | 스마트폰 | 800000 |
2 | 1 | 노트북 | 1200000 |
3 | 2 | 티셔츠 | 30000 |
4 | 3 | 라면 | 3500 |
category_id
: Foreign Key →Category.id
를 참조- 즉, 이 상품이 어떤 카테고리에 속해 있는지를 나타냄
카테고리 테이블의 id는 전체 제품 분류군이고 제품 테이블의 카테고리 id는 제품군에서 파생된 전자제품들이다. 그래서 PK 와 FK로 관계를 형성한 모델 구조이다.